import {cloneVNode, Comment, defineComponent, Fragment, h, Text, VNode} from "vue";

/**
 * 对于文本或SVG，需要用span包裹一下
 * @param s
 */
const wrapTextContent = (s: string | VNode): VNode => {
  return h('span', null, s);
};

/**
 * 判断是否为Object
 * @param val
 */
const isObject = (val: any) => val !== null && typeof val === 'object';

/**
 * 找出第一个合法的子元素
 * @param node
 */
const findFirstLegitChild = (node: VNode[] | undefined): VNode | null => {
  if (!node) return null;
  for (const child of node) {
    if (isObject(child)) {
      switch (child.type) {
        case Comment:
          continue;
        case Text:
        case 'svg':
          return wrapTextContent(child);
        case Fragment:
          return findFirstLegitChild(child.children as VNode[]);
        default:
          return child;
      }
    }
    return wrapTextContent(child);
  }
  return null;
};

const NAME = 'SlotEvents';

const SlotEvents = defineComponent({
  name: NAME,
  setup(_, {slots, attrs}) {
    return () => {
      const defaultSlot = slots.default?.(attrs);
      if (!defaultSlot) return null;
      if (defaultSlot.length > 1) {
        console.warn(`${NAME}: 只需要一个子元素`);
        return null;
      }
      const firstLegitChild = findFirstLegitChild(defaultSlot);
      if (!firstLegitChild) {
        console.warn(`${NAME}: 没有可用的子元素`);
        return null;
      }
      return cloneVNode(firstLegitChild, attrs);
    };
  }
});
export default SlotEvents;
